﻿using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows;
using System.Windows.Media;
using System.Windows.Navigation;
using Microsoft.Devices;
using Microsoft.Phone.Controls;
using Newtonsoft.Json;

namespace ElectricityMate
{
    public partial class MeasurementPage : PhoneApplicationPage
    {
        public MeasurementPage()
        {
            InitializeComponent();
        }

        private readonly PhotoCamera _camera = new PhotoCamera(CameraType.Primary);
        private bool _cameraInitialized;
        private readonly LedDetector _detector = new LedDetector();

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // subscribe frame analysed event
            _detector.FrameAnalysed += _detector_FrameAnalysed;

            // Initialize camera and turn camera to portrait mode
            CamDisplay.RelativeTransform =
                new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 90 };
            // set preview display on
            CamDisplay.SetSource(_camera);

            _camera.Initialized += (sender, args) =>
                {
                    if (!args.Succeeded)
                    {
                        throw new Exception("Camera initialization failed");
                    }
                    _cameraInitialized = true;
                };

            base.OnNavigatedTo(e);
        }

        void _detector_FrameAnalysed(object sender, EventArgs e)
        {
            Dispatcher.BeginInvoke(delegate
                {
#if DEBUG
                    var str = string.Format("FPS: {0}, Peaks: {1}, Pwr: {2}", _detector.FPS, _detector.Peaks,
                                            Math.Round(_detector.GetPowerConsumption(), 2));
                    DebugTxt.Text = str;
#endif
                    var info =
                        string.Format("Power consumption: " + Math.Round(_detector.GetPowerConsumption(), 2) + " kW");
                    InfoTxt.Text = info;
                });
        }
        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            _detector.FrameAnalysed -= _detector_FrameAnalysed;
            base.OnNavigatedFrom(e);
        }

        /// <summary>
        /// Start / stop measuring power consumption
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StartMeasureBtn_OnClick(object sender, RoutedEventArgs e)
        {
            // not yet initialized
            if (!_cameraInitialized)
            {
                // TODO: show error;
                return;
            }
            // if started already
            if (_detector.IsStarted())
            {
                // stop
                StartMeasureBtn.Content = "Start measurement";
                _detector.Stop();
                SaveData();
                System.Diagnostics.Debug.WriteLine("FPS: " + _detector.FPS + " peaks: " + _detector.Peaks + " power: " + Math.Round(_detector.GetPowerConsumption(), 3));
                
                // go straight to past measurements list
                NavigationService.Navigate(new Uri("/PastMeasurementsPage.xaml", UriKind.Relative));
                return;
            }

            // start detector (we need to send dispatcher to avoid cross-thread refs
            _detector.Start(_camera, Dispatcher);

            StartMeasureBtn.Content = "Stop";
        }

        /// <summary>
        /// Save data to isolated storage
        /// </summary>
        private void SaveData()
        {
            if (!App.ViewModel.IsDataLoaded)
            {
                App.ViewModel.LoadData();
            }
            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                var item = new ItemViewModel
                        {
                            AverageHourlyConsumption =
                                "Average hourly consumption: " + Math.Round(_detector.GetPowerConsumption(), 2) + " kWh",
                            DateAndConsumption =
                                DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString()
                        };
                App.ViewModel.Items.Add(item);

                // save data as json
                var json = JsonConvert.SerializeObject(App.ViewModel.Items);
                if (!store.FileExists("measurements.json"))
                {
                    var stre = store.CreateFile("measurements.json");
                    stre.Close();
                }
                using (var stream = store.OpenFile("measurements.json", FileMode.Open, FileAccess.ReadWrite))
                using (var file = new StreamWriter(stream))
                {
                    file.Write(json);
                    file.Close();
                    stream.Close();
                }
            }
        }
    }
}